package base.hex;

import org.apache.commons.codec.binary.Hex;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class HexTest {
    public static void main(String[] args) {

        String base64String = "A2c/AQRowQZlRQBBAEUABWo2AAd9ECcIfbcBCXMCJw==";
        base64String = "A2cxAQRowwZlIQAfACEABWoeAAd94iEIfSgDCXMCJw==";
        base64String = "A2cIAQRolAZlSABDAEgABWoSAAd90wIIffsACXMEJw==";
        base64String = "A2cIAQRoiwZlQgA9AEIABWoAAAd9uQIIfbkACXMGJw==";
        // base64String = "MHhmZjBiZmY=";

        byte[] b2 = Base64.getDecoder().decode(base64String);

        // byte[] b2 = Hex.decodeHex(base64String.toCharArray());

        System.out.println("HexUtils-String: " + new String(b2));

        System.out.println("HEX: ");
        char[] codeChar = Hex.encodeHex(b2);
        for (char c : codeChar) {
            System.out.print(c + ",");
        }

        System.out.println();

        String codeStr = Hex.encodeHexString(b2);
        System.out.println("HexUtils-String: " + codeStr);

        Map<String, Object> map = new HashMap<>();

        new HexTest().parse(b2, map);
        System.out.println(map);

    }

    public void parse(byte[] bytes, Map<String, Object> map) {
        int cursor = 0;

        while (cursor < bytes.length - 1) {

            int b = bytes[cursor];

            switch (b) {

                case 1:
                    cursor += 2;
                    map.put("battery", bytes[cursor]);
                    cursor++;
                    break;
                case 3:
                    cursor += 3;
                    map.put("temperature", hexToInt(bytes, cursor) * 0.1);
                    cursor++;
                    break;
                case 4:
                    cursor += 2;
                    map.put("humidity", hexToUInt(bytes[cursor]) / 2);
                    cursor++;
                    break;
                case 5:
                    cursor += 3;
                    map.put("activity", hexToUInt(bytes, cursor));
                    cursor++;
                    break;
                case 6:
                    cursor += 3;
                    map.put("illumination", hexToUInt(bytes, cursor));
                    cursor += 2;
                    map.put("visible+infrared", hexToUInt(bytes, cursor));
                    cursor += 2;
                    map.put("infrared", hexToUInt(bytes, cursor));
                    cursor++;
                    break;
                case 7:
                    cursor += 3;
                    map.put("CO2", hexToInt(bytes, cursor));
                    cursor++;
                    break;
                case 8:
                    cursor += 3;
                    map.put("tVOC", hexToUInt(bytes, cursor));
                    cursor++;
                    break;
                case 9:
                    cursor += 3;
                    map.put("pressure", hexToUInt(bytes, cursor) / 10);
                    cursor++;
                    break;
            }
        }

    }

    public int hexToUInt(byte b) {
        return b > 0 ? b : b & 0xff;
    }

    public int hexToUInt(byte[] bytes, int cursor) {
        int a = bytes[cursor - 1];
        int b = bytes[cursor] << 8;

        a = a > 0 ? a : a & 0xff;
        b = b > 0 ? b : b & 0xff;

        return (b + a) & 0xffff;
    }

    public int hexToInt(byte[] bytes, int cursor) {
        int val = hexToUInt(bytes, cursor);
        System.out.println(val);
        return val > 0x7fff ? val - 0x10000 : val;
    }

    public void name() {

    }
}
